#include <string.h>
#include <iostream>
using namespace std;

// 模拟RAII类的模版
template<class T1>
class RAII{
public:
    // 1.在构造函数中初始化资源
    RAII(T1 * data)
    :_data(data)
    {
        cout << "RAII()" << endl;
    }
    // 2.在析构函数中释放资源
    ~RAII(){
        if(_data){
            delete _data;
            _data = nullptr;
        }
        cout << "~RAII()" << endl;
    }

    // 4.设置一些访问资源的方法
    T1 * operator->(){
        return _data;
    }

    T1 & operator*(){
        return *_data;
    }
    T1 * get(){
        return _data;
    }


    RAII(const RAII & rhs) = delete;
    // 赋值运算符
    RAII & operator=(const RAII & rhs) = delete;
private:
    // 设置拷贝构造和赋值运算为私有的
    // 实现对象语义
    // 拷贝构造
    // 3.不允许进行复制或者赋值操作
    // 赋值运算符

    T1 * _data;
};

class Computer{
public:
    Computer(const char * name, int price)
    :_name(new char[strlen(name) + 1]())
    ,_price(price)
    {
        strcpy(_name, name);
        cout << "Computer(char *,int)" << endl;
    }
    // Computer类里面有自己的堆栈空间要自己手动释放
    // 不然会出现内存泄漏
    // RAII释放的是自己的内存空间，而Computer类自己申请的
    // 需要自己释放
//#if 0
    ~Computer(){
        if(_name){
            delete[] _name;
            _name = nullptr;
        }
        cout << "~Computer()" << endl;
    }
//#endif
    void print(){
        cout << "_name=" << _name << " _name=" << _name << endl;
    }
private:
    char  * _name;
    int _price;
};

void test(){
    RAII<Computer> raii(new Computer("xiaomi",5999));
    raii->print();


}

int main(int atgc, char * argv[])
{
    test();
    return 0;
}

